<template>
	<form class="change-password-modal px-[25px] md:px-[35px] pt-4 pb-10" @submit.prevent="onEnter">
		<input type="submit" class="hidden" />
		<BaseTip class="mb-4" textT="set.security.popup.password.tip" />
		<BaseInput
			v-model="formValue.oldPassword"
			:name="FormFieldName.password"
			labelT="reset.passwordOld"
			type="password"
			:rules="formRule.oldPassword.result.rules"
			:is-danger="!formRule.oldPassword.result.valid"
			@blur="formRule.oldPassword.validator()"
			@focus="formReset('oldPassword')" />
		<div class="flex justify-end mb-4">
			<base-text text-t="login.forget" class="text-sm app-text-link" @click="onReset()" />
		</div>
		<BaseInput
			v-model="formValue.newPassword"
			:name="FormFieldName.passwordNew"
			labelT="reset.password"
			type="password"
			:rules="formRule.newPassword.result.rules"
			:is-danger="!formRule.newPassword.result.valid"
			@blur="formRule.newPassword.validator()"
			@focus="formReset('newPassword')" />
		<BaseInput
			v-model="formValue.newPassword2"
			:name="FormFieldName.passwordNewConfirm"
			labelT="reset.password2"
			type="password"
			:errorT="formRule.newPassword2.result.textT"
			:is-danger="!formRule.newPassword2.result.valid"
			@blur="formRule.newPassword2.validator()"
			@focus="formReset('newPassword2')" />
		<BaseButton
			class="mt-10"
			type="primary"
			textT="action.confirm"
			:loading="loading"
			@click="onEnter" />
	</form>
</template>

<script setup lang="ts">
import { computed, nextTick, reactive } from 'vue'
import { FormFieldName } from '@/enums'
import { BaseButton, BaseInput, BaseText, BaseTip } from '@/components/base'
import { AccountShowType, Action } from '@/types'
import { useAccountStore, useProfileStore } from '@/store'
import { useRequest } from '@/hooks'
import { updatePassword } from '@/api/account.ts'
import { hasSpace, isLength } from '@/utils'
import { RuleType } from '@/components/base/input-rule/index.vue'

const accountStore = useAccountStore()
const profileStore = useProfileStore()
const formValue = reactive({
	oldPassword: '',
	newPassword: '',
	newPassword2: ''
})
const formRule = reactive({
	oldPassword: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.oldPassword.result = { valid: true })
			if (action === Action.input) formRule.oldPassword.hasInput = true
			if (action === Action.blur && !formRule.oldPassword.hasInput) return
			const value = formValue.oldPassword
			const spaceValid = !!value && !hasSpace(value)
			const rules = [
				{ textT: 'register.passwordRuleLength', valid: isLength(value, 8, 24) && spaceValid },
				{ textT: 'register.passwordRuleChar', valid: /[a-zA-Z]/.test(value) },
				{ textT: 'register.passwordRuleNum', valid: /[0-9]/.test(value) }
			]
			formRule.oldPassword.result = { valid: rules.every(({ valid }) => valid), rules }
		}
	},
	newPassword: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.newPassword.result = { valid: true })
			if (action === Action.input) formRule.newPassword.hasInput = true
			if (action === Action.blur && !formRule.newPassword.hasInput) return
			const value = formValue.newPassword
			const spaceValid = !!value && !hasSpace(value)
			const rules = [
				{ textT: 'register.passwordRuleLength', valid: isLength(value, 8, 24) && spaceValid },
				{ textT: 'register.passwordRuleChar', valid: /[a-zA-Z]/.test(value) },
				{ textT: 'register.passwordRuleNum', valid: /[0-9]/.test(value) }
			]
			formRule.newPassword.result = { valid: rules.every(({ valid }) => valid), rules }
		}
	},
	newPassword2: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.newPassword2.result = { valid: true })
			if (action === Action.input) formRule.newPassword2.hasInput = true
			if (action === Action.blur && !formRule.newPassword2.hasInput) return
			const value = formValue.newPassword2
			let msg = ''
			if (value !== formValue.newPassword) {
				msg = 'reset.password2NoMatch'
			}
			formRule.newPassword2.result = { textT: msg, valid: !msg }
		}
	}
})

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}

const { run, loading } = useRequest(updatePassword, {
	showError: true,
	showSuccess: true,
	onSuccess: () => {
		profileStore.show.updatePassword = false
		accountStore.logout()
		accountStore.showAccount(AccountShowType.login)
	}
})
const onReset = () => {
	if (profileStore.userInfo) {
		const { email, emailVerify, mobile, mobileVerify } = profileStore.userInfo
		if (emailVerify || mobileVerify) {
			profileStore.show.updatePassword = false
			accountStore.showAccount(AccountShowType.forgotPassword)
		} else if (email) {
			profileStore.show.email = true
		} else if (mobile) {
			profileStore.show.mobile = true
		}
	}
}

const submitDisabled = computed(
	() =>
		!formValue.oldPassword ||
		!formValue.newPassword ||
		!formValue.newPassword2 ||
		Object.values(formRule).some(({ result: { valid } }) => !valid)
)

const onSubmit = () => {
	run({ oldPassword: formValue.oldPassword, newPassword: formValue.newPassword })
}

const onEnter = () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	nextTick(() => {
		if (submitDisabled.value) return
		onSubmit()
	})
}
</script>

<style scoped></style>
